package com.devunion.salon.web.action;

import com.devunion.salon.persistence.*;
import com.devunion.salon.persistence.dao.*;
import com.devunion.salon.util.DateFormatter;
import com.devunion.salon.util.TransactionCodeGenerator;
import com.devunion.salon.web.bean.TransactionBean;
import com.devunion.salon.web.form.PaymentForm;
import com.devunion.salon.web.form.TransactionForm;
import org.apache.commons.lang.StringUtils;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.util.LabelValueBean;
import org.springframework.beans.factory.InitializingBean;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Timoshenko Alexander 17.09.2008 : 23:07:50
 */
public class PaymentAction extends CoreAction implements InitializingBean {
    private ChequeDao chequeDao;
    private LocationDao locationDao;
    private ProductDao productDao;
    private ServiceDao serviceDao;
    private EmployeeDao employeeDao;
    private CustomerDao customerDao;
    private GiftCardDao giftCardDao;
    private List<String> payments = new ArrayList<String>();

    public void afterPropertiesSet() throws Exception {
        payments.add(resources.getMessage("modal.add.transaction.payment.amex"));
        payments.add(resources.getMessage("modal.add.transaction.payment.visa"));
        payments.add(resources.getMessage("modal.add.transaction.payment.mastercard"));
        payments.add(resources.getMessage("modal.add.transaction.payment.cheque"));
        payments.add(resources.getMessage("modal.add.transaction.payment.cache"));
        payments.add(resources.getMessage("modal.add.transaction.payment.giftcard"));
    }

    public void setChequeDao(ChequeDao chequeDao) {
        this.chequeDao = chequeDao;
    }

    public void setLocationDao(LocationDao locationDao) {
        this.locationDao = locationDao;
    }

    public void setProductDao(ProductDao productDao) {
        this.productDao = productDao;
    }

    public void setServiceDao(ServiceDao serviceDao) {
        this.serviceDao = serviceDao;
    }

    public void setEmployeeDao(EmployeeDao employeeDao) {
        this.employeeDao = employeeDao;
    }

    public void setCustomerDao(CustomerDao customerDao) {
        this.customerDao = customerDao;
    }

    public void setGiftCardDao(GiftCardDao giftCardDao) {
        this.giftCardDao = giftCardDao;
    }

    public ActionForward pay(ActionMapping actionMapping, ActionForm actionForm,
                             HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        ActionMessages messages = new ActionMessages();

        PaymentForm paymentForm = (PaymentForm) actionForm;
        String submittedValue = paymentForm.getSubmittedValue();

        if (!StringUtils.isBlank(submittedValue)) {
            Map<Long, Employee> id2employee = new HashMap<Long, Employee>();
            TransactionForm transactionForm = (TransactionForm) httpServletRequest.getSession().getAttribute("transaction");

            Cheque cheque = new Cheque();
            cheque.setNumber(TransactionCodeGenerator.next());
            cheque.setCreationDate(DateFormatter.getSQLDate(transactionForm.getHiddenDate()));
            cheque.setDiscount(paymentForm.getDiscount());

            Location location = locationDao.getLocation(getUsername());
            cheque.setLocation(location);

            Payment firstPayment = getPaymentByType(paymentForm.getType());
            firstPayment.setValue(paymentForm.getCheckPayment() ? Float.valueOf(paymentForm.getAmount())
                    : transactionForm.getTotalPriceAndTaxes());
            cheque.setPayment(firstPayment);

            if (!StringUtils.isBlank(paymentForm.getGiftcard())) {
                GiftCard giftCard = giftCardDao.getCustomerGiftcard(paymentForm.getGiftcard());
                if (giftCard != null) {
                    Float amount = giftCard.getAmount() - firstPayment.getValue();
                    giftCard.setAmount(amount >= 0 ? amount : 0f);
                    giftCardDao.update(giftCard);
                }
            }

            if (paymentForm.getCheckPayment()) {
                Payment secondPayment = new Payment(paymentForm.getSecondPaymentMethod());
                secondPayment.setValue(paymentForm.getSecondPaymentAmount());
                cheque.setSecondPayment(secondPayment);
            }

            List<Transaction> transactions = new ArrayList<Transaction>();
            for (TransactionBean bean : transactionForm.getTransactions()) {
                Transaction transaction = new Transaction();
                transaction.setNumber(bean.getTransNumber());

                if (bean.getEmployee() != null) {
                    Employee employee;
                    if ((employee = id2employee.get(bean.getEmployee().getId())) == null) {
                        employee = employeeDao.getByKey(bean.getEmployee().getId());
                        id2employee.put(employee.getId(), employee);
                    }
                    transaction.setEmployee(employee);
                }
                if (bean.getProduct() != null) {
                    transaction.setProduct(productDao.getByKey(bean.getProduct().getKey()));
                } else if (bean.getService() != null) {
                    transaction.setService(serviceDao.getByKey(bean.getService().getKey()));
                } else if (bean.getGiftcardBean() != null) {
                    GiftCard giftCard = new GiftCard();
                    giftCard.setAmount(bean.getGiftcardBean().getAmount());
                    giftCard.setCode(bean.getTransNumber());
                    giftCard.setCreated(DateFormatter.getSQLDate(transactionForm.getHiddenDate()));
                    giftCard.setLocation(location);
                    giftCard.setTransaction(transaction);
                    transaction.setGiftCard(giftCard);
                }

                transaction.setQuantity(bean.getQuantity());
                transactions.add(transaction);
            }
            cheque.setTransactions(transactions);
            cheque.setCustomer(customerDao.getByKey(transactionForm.getCustomerBean().getId()));
            chequeDao.saveOrUpdate(cheque);

            httpServletRequest.getSession().removeAttribute("transaction");
            httpServletRequest.getSession().removeAttribute("paymentForm");

            return actionMapping.findForward("success");
        }

        if (paymentForm.getMethods().isEmpty()) {
            for (String payment : payments) {
                paymentForm.getMethods().add(new LabelValueBean(payment, payment));
            }
        }

        return actionMapping.getInputForward();
    }

    private Payment getPaymentByType(String type) {
        switch (type.charAt(0)) {
            case '1':
                return new Payment(payments.get(0));
            case '2':
                return new Payment(payments.get(1));
            case '3':
                return new Payment(payments.get(2));
            case '4':
                return new Payment(payments.get(3));
            case '5':
                return new Payment(payments.get(4));
            case '6':
                return new Payment(payments.get(5));
            default:
                return new Payment("");
        }
    }
}
